package org.jsola.hr.service.excel;

import com.alibaba.excel.context.AnalysisContext;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.jsola.common.BeanKit;
import org.jsola.common.DateKit8;
import org.jsola.hr.dto.SaleServerCostRecordImportDTO;
import org.jsola.hr.entity.CompanyDO;
import org.jsola.hr.entity.SaleServerCostRecordDO;
import org.jsola.hr.service.ICompanyService;
import org.jsola.hr.service.ISaleServerCostRecordService;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author lyh
 */
@Slf4j
@Data
@EqualsAndHashCode(callSuper = true)
@Component
public class SaleServerCostRecordListener extends BaseAnalysisEventListener<SaleServerCostRecordImportDTO> {

    /**
     * List最大盛装数据条数
     */
    private static final Integer MAX_COUNT = 2000;

    /**
     * 入库数据
     */
    private List<SaleServerCostRecordImportDTO> saveDataList = new ArrayList<>();

    /**
     * 失败列表
     */
    private List<SaleServerCostRecordImportDTO> failList = new ArrayList<>();

    /**
     * 用工单位名称为空
     */
    private static final String COMPANY_NAME_NULL = "用工单位名称为空;";

    /**
     * 未在系统中查找到用工单位，请确认用工单位名称是否有误
     */
    private static final String COMPANY_NOT_FIND = "未在系统中查找到用工单位，请确认用工单位名称是否有误;";

    /**
     * 月份为空
     */
    private static final String COST_MONTH_NULL = "月份为空;";

    /**
     * 服务费金额为空
     */
    private static final String SERVER_COST_NULL = "服务费金额为空;";

    /**
     * 服务费金额格式错误
     */
    private static final String SERVER_COST_FORMAT = "服务费金额格式错误;";

    /**
     * 月份格式
     */
    private static final String MONTH_FORMAT = "请正确填写月份;";

    /**
     * 服务费已被导入过，本次导入已被忽略
     */
    private static final String MONTH_REPEAT = "服务费已被导入过，本次导入已被忽略;";

    /**
     * 导入数据重复
     */
    private static final String IMPORT_REPEAT = "导入数据重复;";

    /**
     * 导入成功条数
     */
    private int successCount = 0;

    /**
     * 导入成功条数
     */
    private int allCount = 0;

    /**
     * 导入成功条数
     */
    private int failCount = 0;

    @Override
    public void invoke(SaleServerCostRecordImportDTO data, AnalysisContext context) {
        // 当前行号
        int row = context.readRowHolder().getRowIndex();
        dataList.add(data);
        allCount++;
        if (dataList.size() >= MAX_COUNT) {
            // 入库
            saveData();
            saveDataList.clear();
        }
    }

    @Override
    public void saveData() {
        ISaleServerCostRecordService saleServerCostRecordService = BeanKit.getBean(ISaleServerCostRecordService.class);
        checkError(dataList, saleServerCostRecordService);
        saleServerCostRecordService.saveImportList(saveDataList, tokenUser);

    }

    /**
     * 错误数据校验
     */
    private void checkError(List<SaleServerCostRecordImportDTO> dataList,
                            ISaleServerCostRecordService saleServerCostRecordService) {
        Map<String, List<String>> repeatCheck = new HashMap<>(16);
        List<String> companyNameList = dataList.stream()
                .map(SaleServerCostRecordImportDTO::getCompanyName).collect(Collectors.toList());
        ICompanyService companyService = BeanKit.getBean(ICompanyService.class);
        List<CompanyDO> companyList = companyService.selectByNameList(companyNameList, tokenUser.getSiteId());
        Map<String, CompanyDO> companyMap = companyList.stream().collect(Collectors.toMap(CompanyDO::getName, v -> v));
        for (SaleServerCostRecordImportDTO importData : dataList) {
            Boolean serverCostNull = false;
            boolean errorFlag = false;
            StringBuilder errorInfo = new StringBuilder();
            // 校验用工单位名称
            CompanyDO company = companyMap.get(importData.getCompanyName());
            if (StringUtils.isEmpty(importData.getCompanyName())) {
                errorFlag = true;
                errorInfo.append(COMPANY_NAME_NULL);
            } else {
                if (ObjectUtils.isEmpty(company)) {
                    errorFlag = true;
                    errorInfo.append(COMPANY_NOT_FIND);
                } else {
                    importData.setCompanyId(company.getId());
                }
            }
            // 校验服务费
            String serverCost = importData.getServerCost();
            if (StringUtils.isEmpty(serverCost)) {
                errorFlag = true;
                errorInfo.append(SERVER_COST_NULL);
                serverCostNull = true;
            } else {
                if (checkServiceCost(serverCost)) {
                    errorFlag = true;
                    errorInfo.append(SERVER_COST_FORMAT);
                }
            }
            // 校验月份
            String costMonth = importData.getCostMonth();
            if (StringUtils.isEmpty(costMonth)) {
                errorFlag = true;
                errorInfo.append(COST_MONTH_NULL);
            } else {
                if (checkMonth(costMonth)) {
                    errorFlag = true;
                    errorInfo.append(MONTH_FORMAT);
                } else {
                    if (!ObjectUtils.isEmpty(company)) {
                        List<SaleServerCostRecordDO> recordList = saleServerCostRecordService
                                .selectCompanyRecordByMonth(company.getId(), costMonth, tokenUser);
                        if (!CollectionUtils.isEmpty(recordList)) {
                            errorFlag = true;
                            errorInfo.append(MONTH_REPEAT);
                            if(!serverCostNull){
                                importData.setOverlaid(true);
                            }
                        } else {
                            // 还得判断导入数据里面是否有重复的
                            List<String> monthList = repeatCheck.get(company.getId());
                            if (CollectionUtils.isEmpty(monthList)) {
                                List<String> monthCheck = new ArrayList<>();
                                monthCheck.add(costMonth);
                                repeatCheck.put(company.getId(), monthCheck);
                            } else {
                                if(monthList.contains(costMonth)){
                                    errorFlag = true;
                                    errorInfo.append(company.getName()).append(costMonth).append(IMPORT_REPEAT);
                                } else {
                                    monthList.add(costMonth);
                                }
                            }
                        }
                    }
                }
            }
            if (errorFlag) {
                importData.setErrorInfo(errorInfo.toString());
                failList.add(importData);
                failCount++;
            } else {
                saveDataList.add(importData);
                successCount++;
            }
        }
    }

    /**
     * 校验月份
     */
    private boolean checkMonth(String costMonth) {
        costMonth = costMonth + "-01";
        try {
            DateKit8.parseDate(costMonth);
        } catch (Exception e) {
            return true;
        }
        return false;
    }

    /**
     * 校验服务费
     */
    private boolean checkServiceCost(String serviceCost) {
        try {
            new BigDecimal(serviceCost);
        } catch (Exception e) {
            return true;
        }
        return false;
    }
}
